package edu.hawaii.duedates.parser;

import java.util.ArrayList;
import java.util.List;

/**
 * Option class which describes the basis of what an option contains.
 * Basic attributes consist of the following:
 * 1) name
 * 2) usage
 * 3) message (optional)
 * 4) parameters
 * 
 * @author Anthony M. Du
 *
 */
public class Option implements Comparable<Option> {
  // optName is the option's name.
  private final String optName;
  // optMessage contains the option's message.
  private String optMessage;
  // optUsage contains the option's usage (message).
  private String optUsage;
  // parameters contains the option's parameters.
  private List<String> parameters = new ArrayList<String>();
  
  /**
   * Default option constructor.
   * Initializes all fields.
   */
  public Option() {
    optName = "";
    optMessage = "";
    optUsage = "";
  }
  
  /**
   * Creates an Option object with one required field.
   * @param n  contains the option's name.
   */
  public Option(String n) {
    optName = n;
  }
  
  /**
   * Creates an Option object with one required field.
   * @param n  contains the option's name.
   * @param p  contains the option's parameter(s).
   */
  public Option(String n, List<String> p) {
    optName = n;
    parameters = p;
  }
  
  /**
   * Creates an Option object with required fields.
   * @param n  contains the option's message.
   * @param u  contains the option's usage message.
   */
  public Option(String n, String u) {
    optName = n;
    optUsage = u;
  }
  
  /**
   * Creates an Option object with required fields.
   * @param n  contains the option's message.
   * @param u  contains the option's usage message.
   * @param p  contains the option's parameter(s).
   */
  public Option(String n, String u, List<String> p) {
    optName = n;
    optUsage = u;
    parameters = p;
  }
  
  /**
   * Creates an Option object and initializes all fields.
   * @param n  contains the option's name.
   * @param m  contains the option's message.
   * @param u  contains the option's usage message.
   */
  public Option(String n, String m, String u) {
    optName = n;
    optMessage = m;
    optUsage = u;
  }
  
  /**
   * Creates an Option object and initializes all fields.
   * @param n  contains the option's name.
   * @param m  contains the option's message.
   * @param u  contains the option's usage message.
   * @param p  contains the option's parameter(s).
   */
  public Option(String n, String m, String u, List<String> p) {
    optName = n;
    optMessage = m;
    optUsage = u;
    parameters = p;
  }
  
  /**
   * Adds a parameter to the list of parameters.
   * @param p  contains a parameter.
   */
  public void addParam(String p) {
    parameters.add(p);
  }
  
  /**
   * Gets the list of option's parameter(s).
   * @return parameters  contains list of parameters.
   * @return
   */
  public List<String> getOptParams() {
    return parameters;
  }
  
  /**
   * Checks to see if option has list of parameters.
   * @return true/false.
   */
  public boolean hasParams() {
    return !parameters.isEmpty();
  }
  
  /**
   * Gets the option's name.
   * @return String  containing the option's name.
   */
  public String getOptName() {
    return optName;
  }

  /**
   * Gets the option's message.
   * @return String  containing the option's message
   */
  public String getOptMessage() {
    return optMessage;
  }

  /**
   * Gets the option's usage.
   * @return String  containing the option's usage.
   */
  public String getOptUsage() {
    return optUsage;
  }
  
  /**
   * CompareTo method for Option class.
   * @param option  Option object.
   * @return int  integer value of 0, -1, or 1.
   */
  public int compareTo(Option option) {
    return this.optName.compareTo(option.getOptName());
  }
  
  /**
   * Equals is used to check equality of a give book object.
   * @param obj The object being passed for equality check.
   * @return boolean value of true/false.
   */
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Option) {
      Option b = (Option) obj;
      return b.getOptName().equals (this.optName);
    }
    return false;
  }
  
  /**
   * HashCode for generating a unique hashcode coupled by the option's attributes.
   * @return int a unique book hashcode.
   */
  @Override 
  public int hashCode() {
    return this.optName.hashCode();
  }
}
